package com.nercel.dsj.gksales.service.impl;

import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.nercel.dsj.gksales.dao.mapper.SellRecordMapper;
import com.nercel.dsj.gksales.exception.ResponseCode;
import com.nercel.dsj.gksales.exception.RestApiException;
import com.nercel.dsj.gksales.model.ListResult;
import com.nercel.dsj.gksales.model.PayType;
import com.nercel.dsj.gksales.model.QueryParams;
import com.nercel.dsj.gksales.model.dto.SalesRecordResultDTO;
import com.nercel.dsj.gksales.model.entity.Payment;
import com.nercel.dsj.gksales.model.entity.SellRecord;
import com.nercel.dsj.gksales.model.entity.User;
import com.nercel.dsj.gksales.service.SellRecordService;
import com.nercel.dsj.gksales.service.UserService;
import com.nercel.dsj.gksales.util.SignUtil;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Transactional
public class SellRecordServiceImpl implements SellRecordService {

    static final String TEST_KEY = "1EF1236C2FCDE44AC00A37EDA2C4F7F7";

    private final SellRecordMapper sellRecordMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${app.gkServiceApi}")
    private String gkServiceApi;

    @Autowired
    private UserService userService;

    @Override
    public void save(SellRecord sellRecord) {
        sellRecordMapper.insertSelective(sellRecord);
    }

    @Override
    public void update(SellRecord sellRecord) {
        sellRecordMapper.updateByPrimaryKeySelective(sellRecord);
    }

    @Override
    public SellRecord findById(Integer integer) {
        return sellRecordMapper.selectByPrimaryKey(integer);
    }

    @Override
    public List<SellRecord> listAll() {
        return null;
    }

    @Override
    public void delete(Integer integer) {
        sellRecordMapper.deleteByPrimaryKey(integer);
    }

    @Override
    public ListResult<SalesRecordResultDTO> listWithPaging(QueryParams queryParams) {
        Page<SalesRecordResultDTO> page = PageHelper.startPage(queryParams.getPageNumber(), queryParams.getPageSize());
        sellRecordMapper.query(queryParams);
        return new ListResult<>(page);
    }

    @Override
    public List<Map<String, Object>> salesRecordsStatistics(QueryParams queryParams) {
        return sellRecordMapper.sellRecordsStatistics(queryParams);
    }

    @Override
    public List<SalesRecordResultDTO> list(QueryParams queryParams) {
        return sellRecordMapper.query(queryParams);
    }

    @Async
    @Override
    public void saveAndActivateWithPayment(Payment payment) {
        User sales = userService.findByPhone(payment.getSalesPhone());
        Integer salesId = sales == null ? null : sales.getId();
        SellRecord params = new SellRecord();
        if (salesId != null) {
            params.setUserId(sales.getId());
            params.setRegionId(sales.getProvinceId());
        }
        params.setCreateTime(new Date());
        params.setCustomerPhone(payment.getValue1());
        params.setPayType(payment.getType() == PayType.ALI_PAY ? 4 : 5);
        params.setAmount(payment.getAmount());
        saveAndActivate(params, salesId);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void saveAndActivate(SellRecord sellRecord, Integer salesUserId) {
        String url = gkServiceApi + "/api/v1/service/vip";
        String orderNumber = String.valueOf(Instant.now().toEpochMilli());
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("userPhone", sellRecord.getCustomerPhone());
        requestMap.put("source", 2); // 来源 1激活码 2营销工具 3自行开通 4码上购
        if (salesUserId != null) {
            User salesUser = userService.findById(salesUserId);
            requestMap.put("salesPhone", salesUser == null ? "" : salesUser.getPhone()); // 销售人员的电话
        }
        requestMap.put("payType", sellRecord.getPayType());
        requestMap.put("batch", sellRecord.getBatch());
        requestMap.put("orderNumber", orderNumber);
        requestMap.put("createTime", Instant.now().getEpochSecond());
        requestMap.put("sendSms", true);
        requestMap.put("amount", sellRecord.getAmount());
        requestMap.put("value1", sellRecord.getRegionId());
        requestMap.put("remark", sellRecord.getRemark());
        String sign = SignUtil.sign(requestMap, TEST_KEY);
        log.info("传入时的sign:{},传入时的Map:{},传入时的key:{}", sign, requestMap.toString(), TEST_KEY);
        requestMap.put("sign", sign);
        HttpHeaders headers = new HttpHeaders(); // http请求头
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8); // 请求头设置属性
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<Map<String, Object>>(requestMap, headers);
        Map<String, Object> responseMap = restTemplate.postForObject(url, requestEntity, Map.class);
        // TODO 如果请求没有返回，会有问题
        if (responseMap != null && ResponseCode.SUCCESS.getCode().intValue() == (int)responseMap.get("code")) {
            Map<String, Object> data = (Map<String, Object>)responseMap.get("data");
            sellRecord.setOrderNumber(orderNumber);
            sellRecord.setCustomerId((Integer)data.get("userId"));
            log.info("sellRecord对象：{}-------------", sellRecord);
            sellRecord.setDeleted(false);
            sellRecordMapper.insertSelective(sellRecord);
        } else {
            throw new RestApiException("接口调用失败！", ResponseCode.INTERNAL_SERVER_ERROR.getCode());
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public void saveAndActivateBatch(List<SellRecord> sellRecords, Integer salesUserId) {
        String url = gkServiceApi + "/api/v1/service/vip/batch";
        String orderNumber = String.valueOf(Instant.now().toEpochMilli());
        Map<String, Object> requestMap = new HashMap<>();
        // 手机号用逗号分隔
        requestMap.put("phones",
            sellRecords.stream().map(SellRecord::getCustomerPhone).collect(Collectors.joining(",")));
        requestMap.put("source", 2); // 来源 1激活码 2营销工具 3自行开通 4码上购
        if (salesUserId != null) {
            User salesUser = userService.findById(salesUserId);
            requestMap.put("salesPhone", salesUser == null ? "" : salesUser.getPhone()); // 销售人员的电话
        }

        requestMap.put("payType", sellRecords.stream().findAny().get().getPayType());
        requestMap.put("batch", sellRecords.stream().findAny().get().getBatch());
        requestMap.put("orderNumber", orderNumber);
        requestMap.put("createTime", Instant.now().getEpochSecond());
        requestMap.put("sendSms", true);
        requestMap.put("amount", sellRecords.stream().findAny().get().getAmount());
        requestMap.put("value1", sellRecords.stream().findAny().get().getRegionId());
        requestMap.put("remark", sellRecords.stream().findAny().get().getRemark());
        String sign = SignUtil.sign(requestMap, TEST_KEY);
        log.info("传入时的sign:{},传入时的Map:{},传入时的key:{}", sign, requestMap.toString(), TEST_KEY);
        requestMap.put("sign", sign);
        HttpHeaders headers = new HttpHeaders(); // http请求头
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8); // 请求头设置属性
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<Map<String, Object>>(requestMap, headers);
        Map<String, Object> responseMap = restTemplate.postForObject(url, requestEntity, Map.class);
        // TODO 如果请求没有返回，会有问题
        if (responseMap != null && ResponseCode.SUCCESS.getCode().intValue() == (int)responseMap.get("code")) {
            for (SellRecord sr : sellRecords) {
                sr.setOrderNumber(orderNumber);
                sr.setDeleted(false);
                sr.setUserId(salesUserId);
                sr.setCreateTime(new Date());
                log.info("sellRecord对象：{}-------------", sr);
                sellRecordMapper.insertSelective(sr);
            }
        } else {
            throw new RestApiException("接口调用失败！", ResponseCode.INTERNAL_SERVER_ERROR.getCode());
        }

    }

}
